 
 /*------------------------------------------------------------------------
    File        : KeySet
    Purpose     : 
    Syntax      : 
    Description : 
    @author hdaniels
    Created     : apr 2010
    Notes       : no empty constructor, specialized for KeySet of IMap 
                 - Changes to the map are reflected here, and vice-versa. 
                 - Supports removal and removes the corresponding map entry from the map
                   (Iterator.remove, Collection.remove, removeAll, retainAll and clear) .
                 - Do not support add and addAll.   
                 - no empty constructor, specialised for IMap 
  ----------------------------------------------------------------------*/

routine-level on error undo, throw.

using Progress.Lang.Object.
using OpenEdge.Lang.Collections.ICollection.
using OpenEdge.Lang.Collections.IMap. 
using OpenEdge.Lang.Collections.IIterator. 
using OpenEdge.Lang.Collections.ISet. 
using OpenEdge.Lang.Collections.KeySet. 
using OpenEdge.Lang.Collections.ValueCollection. 
 
class OpenEdge.Lang.Collections.KeySet inherits ValueCollection implements ISet: 
  
        
    constructor public KeySet (poMap as IMap,phTT as handle,pcKeyField as char):
        super (poMap,phTT,pcKeyField ).        
    end constructor.
    
    method public override logical Contains(poObj as Object):        
         return OwningMap:ContainsKey(poObj).
    end method.
   
    method public logical ContainsAll(collection as ICollection):            
        define variable iterator as IIterator no-undo.
        define variable found    as logical   no-undo.
        iterator = collection:Iterator(). 
        do while iterator:HasNext():
            if not this-object:Contains(iterator:Next()) then 
                return false.
            found = true.      
        end.    
        return found.         
    end method.
    
    /* Equals if Set and every member of the specified set is contained in this set */
    method public override logical Equals(o as Object):
        define variable oSet as ISet no-undo.
        define variable oIter as IIterator no-undo.
        if super:Equals(o) then 
            return true.
        if type-of(o,ISet) then
        do:
            oSet = cast(o,ISet).
            if oSet:Size = Size then
            do:
                oIter = Iterator().
                do while oIter:HasNext():
                    if oSet:Contains(oIter:Next()) = false then
                        return false. 
                end.    
                return true.
            end.    
        end.
        return false.    
    end method.   
     
    method public override logical Remove( poOld as Object ):
         define variable i as integer no-undo.
         /* OwningMap:Remove() returns oldvalue, but it could be unknown, so use size to check if deleted */
         i = Size.  
         OwningMap:Remove(poOld).
         if i > Size then 
             return true.
         return false.    
    end method.
    
    method public override logical RemoveAll(collection as ICollection):
        define variable iterator   as IIterator no-undo.         
        define variable anyRemoved as logical no-undo.
        iterator = collection:Iterator().
        do while iterator:HasNext():
            if Remove(iterator:Next()) then 
                anyRemoved = true. 
        end.
        return anyRemoved.
    end method.
    
    method public override logical RetainAll(collection as ICollection):
        define variable iterator   as IIterator no-undo.    
        define variable oObj      as Object no-undo.     
        define variable anyRemoved as logical no-undo.
        iterator = collection:Iterator().
        do while iterator:HasNext():
            oObj = iterator:Next().
            if not Contains(oObj) then
            do:
                Remove(oObj). 
                anyRemoved = true. 
            end.
        end.
        return anyRemoved.
    end method.
     
end class.